import * as THREE from 'three'
/* 后处理效果 */
// 合成器
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'
// 处理过程
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js'
import { OutlinePass } from 'three/addons/postprocessing/OutlinePass.js'
import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'
import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'
import { FXAAShader } from 'three/addons/shaders/FXAAShader.js'
/**
 *
 * @param {THREE.Scene} scene 场景
 * @param {THREE.PerspectiveCamera|THREE.OrthographicCamera} camera 相机
 * @param {THREE.WebGLRenderer} renderer 渲染器
 */
export const initComposer = (scene, camera, renderer) => {
  const renderPass = new RenderPass(scene, camera)
  /* 炫光效果 */
  const bloomPass = new UnrealBloomPass(
    new THREE.Vector2(window.innerWidth, window.innerHeight),
    1,
    0.5,
    0,
  )

  const bloomComposer = new EffectComposer(renderer)
  bloomComposer.renderToScreen = false
  bloomComposer.addPass(renderPass)
  bloomComposer.addPass(bloomPass)

  const mixPass = new ShaderPass(
    new THREE.ShaderMaterial({
      uniforms: {
        baseTexture: { value: null },
        bloomTexture: { value: bloomComposer.renderTarget2.texture },
      },
      vertexShader: /* glsl */ `
        varying vec2 vUv;
        void main() {
          vUv = uv;
          gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
        }
      `,
      fragmentShader:/* glsl */ `
        uniform sampler2D baseTexture;
        uniform sampler2D bloomTexture;
        varying vec2 vUv;
        void main() {
          gl_FragColor = ( texture2D( baseTexture, vUv ) + vec4( 1.0 ) * texture2D( bloomTexture, vUv ) );
        }
      `,
      defines: {},
    }),
    'baseTexture',
  )
  mixPass.needsSwap = true 

  const outlinePass = new OutlinePass(
    new THREE.Vector2(window.innerWidth, window.innerHeight),
    scene,
    camera,
  )
  outlinePass.edgeStrength = 20 // 边缘光强
  outlinePass.edgeGlow = 1 // 边缘范围 [0,1]
  outlinePass.edgeThickness = 3 // 边缘厚度
  outlinePass.pulsePeriod = 3 // 边缘闪烁
  outlinePass.downSampleRatio = 2 // 边缘弯曲度
  outlinePass.visibleEdgeColor.set('#022dad')
  outlinePass.hiddenEdgeColor.set('#022dad')

  const dangerOutlinePass = new OutlinePass(
    new THREE.Vector2(window.innerWidth, window.innerHeight),
    scene,
    camera,
  )
  dangerOutlinePass.edgeStrength = 10 // 边缘光强
  dangerOutlinePass.edgeGlow = 0.5 // 边缘范围 [0,1]
  dangerOutlinePass.edgeThickness = 3 // 边缘厚度
  dangerOutlinePass.pulsePeriod = 3 // 边缘闪烁
  dangerOutlinePass.downSampleRatio = 2 // 边缘弯曲度
  dangerOutlinePass.visibleEdgeColor.set('red')
  dangerOutlinePass.hiddenEdgeColor.set('red')

  const outputPass = new OutputPass()

  const fxaaPass = new ShaderPass(FXAAShader)
  fxaaPass.uniforms['resolution'].value.set(
    1 / window.innerWidth / window.devicePixelRatio,
    1 / window.innerHeight / window.devicePixelRatio,
  )

  const composer = new EffectComposer(renderer)
  composer.setPixelRatio(window.devicePixelRatio)

  composer.addPass(renderPass)
  // composer.addPass(mixPass)
  composer.addPass(outlinePass)
  composer.addPass(dangerOutlinePass)
  composer.addPass(outputPass)
  composer.addPass(fxaaPass)

  return {
    renderPass,
    // bloomComposer,
    // bloomPass,
    composer,
    // mixPass,
    outlinePass,
    dangerOutlinePass,
    outputPass,
    fxaaPass,
  }
}

export const BLOOM_SCENE = 1
const bloomLayer = new THREE.Layers()
bloomLayer.set(BLOOM_SCENE)
const darkMaterial = new THREE.MeshBasicMaterial({ color: 'black' })
const materials = new Map()
export function darkenNonBloomed(obj) {
  if (obj.isMesh && bloomLayer.test(obj.layers) === false) {
    materials.set(obj.uuid, obj.material)
    obj.material = darkMaterial
  }
}

export function restoreMaterial(obj) {
  if (materials.has(obj.uuid)) {
    obj.material = materials.get(obj.uuid)
    materials.delete(obj.uuid)
  }
}
